Skip to content

[codex] canonicalize client timestamps#4112

Merged
juliusmarminge merged 1 commit into
pingdotgg:mainfrom
maxwellyoung:codex/canonicalize-client-timestamps
Jul 18, 2026
Merged

[codex] canonicalize client timestamps#4112
juliusmarminge merged 1 commit into
pingdotgg:mainfrom
maxwellyoung:codex/canonicalize-client-timestamps

Conversation

@maxwellyoung

@maxwellyoung maxwellyoung commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Fixes #3983.

What changed

  • assign canonical timestamps to client orchestration commands when the server receives them
  • apply the same receipt timestamp to nested thread creation metadata when a first turn bootstraps a thread
  • cover both ordinary timestamped commands and bootstrap turns with regression tests

Why

Clients currently generate createdAt from their local clocks. If a client clock is ahead, that future timestamp reaches persisted events and projections, so an older user message can sort after its assistant response and after genuinely newer prompts.

Canonicalizing at the server boundary keeps persisted chronology consistent across web and desktop clients while leaving internal server-generated command timestamps unchanged.

This is forward-only: it prevents new skewed records but does not migrate timestamps that are already persisted.

Verification

  • vp check (passes with 10 pre-existing warnings in unrelated web files)
  • vp run typecheck
  • vp test (4,756 passed, 7 skipped)
  • git diff --check

Note

Canonicalize client timestamps in normalizeDispatchCommand with server receipt time

  • Adds canonicalizeClientCommandTimestamps in Normalizer.ts that replaces client-supplied createdAt with the server's receipt timestamp.
  • For thread.turn.start commands that include bootstrap.createThread, the bootstrap's createdAt is also overwritten.
  • normalizeDispatchCommand now calls this before any other normalization logic.
  • Behavioral Change: client-provided createdAt values on all dispatched commands are now silently overwritten with the server receipt time.

Macroscope summarized 3337346.


Note

Medium Risk
Silently overwrites client timestamps on every dispatched command, which changes persisted event ordering for all clients but is scoped to the normalization boundary and covered by tests.

Overview
Client orchestration commands no longer persist client-supplied createdAt values. normalizeDispatchCommand now stamps commands with the server’s receipt time via new canonicalizeClientCommandTimestamps, applied before workspace and attachment normalization on both HTTP and WebSocket dispatch paths.

For thread.turn.start commands that bootstrap a new thread, the nested bootstrap.createThread.createdAt is overwritten with the same receipt timestamp so thread creation and the first turn stay in order when client clocks are skewed. Regression tests cover a plain timestamped command and a bootstrap turn.

This is forward-only: existing persisted timestamps are unchanged.

Reviewed by Cursor Bugbot for commit 3337346. Bugbot is set up for automated code reviews on this repo. Configure here.

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4239b51b-c002-43a3-8c1d-d24f76dc9c3b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 18, 2026
@maxwellyoung
maxwellyoung marked this pull request as ready for review July 18, 2026 00:28
@macroscopeapp

macroscopeapp Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

This PR adds server-side timestamp canonicalization to ensure consistent timestamps regardless of client clock drift. The change is focused, well-tested, and follows a standard pattern for data integrity.

You can customize Macroscope's approvability policy. Learn more.

@juliusmarminge
juliusmarminge merged commit da3c203 into pingdotgg:main Jul 18, 2026
21 checks passed
adamfgr pushed a commit to agriffiths-bots/t3code that referenced this pull request Jul 19, 2026
* Fix dropped events during initial thread snapshot (pingdotgg#4079)

* [codex] fix mobile composer Enter behavior (pingdotgg#3930)

Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: codex <codex@users.noreply.github.com>

* feat: draft hero landing on the index route (pingdotgg#4055)

Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>

* feat: file explorer mention actions and zoom-aware context menus (pingdotgg#4054)

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>

* fix(web): avoid duplicate mention text on paste

Co-authored-by: codex <codex@users.noreply.github.com>

* fix(mobile): restore iOS home screen branding (pingdotgg#4025)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* perf(client): defer active thread cache writes (pingdotgg#4006)

* Default diffs to working changes (pingdotgg#3974)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* Add Grok to marketing site provider list (pingdotgg#3484)

* Fix reopening existing Diff tab (pingdotgg#3973)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* Fix sending messages during active turns (pingdotgg#3919)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* [codex] Route OpenCode missing-session errors through Effect (pingdotgg#3608)

Co-authored-by: Codex <codex@openai.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>

* [fix/feat:ui] Show default option badge (pingdotgg#3232)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* [fix/feat:ui] Preserve open-in editor brand colors (pingdotgg#3225)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* fix(web): handle macOS Home and End in composer (pingdotgg#2508)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* Allow failed remote environments to be removed (pingdotgg#4084)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* [codex] canonicalize client timestamps (pingdotgg#4112)

* [fix/feat:ui] Make selected menu checks blue (pingdotgg#3234)

Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: codex <codex@users.noreply.github.com>

* fix(desktop): Validate WSL node version against engine range after probe success (pingdotgg#3621)

Co-authored-by: Julius Marminge <julius0216@outlook.com>

* Refresh splash screen and favicon branding (pingdotgg#4120)

* Add terminal selection copy action (pingdotgg#2904)

* fix(sync): reconcile upstream changes with fork-local behaviour

Two merge-introduced incompatibilities from the 20260719 upstream sync:

- Normalizer: upstream's client-timestamp canonicalization (da3c203)
  rewrote bootstrap.createThread.createdAt, which BootstrapTurnStartDispatcher
  uses to fingerprint a replayed bootstrap turn against the thread it already
  created. Every retry would miss that check and create a duplicate thread.
  Keep the client's bootstrap timestamp as the stable identity; the turn-level
  createdAt is still canonicalized.

- ThreadTerminalDrawer: upstream's terminal selection copy action (1735e27)
  passed a Terminal to writeSystemMessage, which this fork narrowed to accept
  a TerminalWriteQueue. Use terminalWriterRef, matching the other call sites.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Signed-off-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Ishan <ishansachu1@gmail.com>
Co-authored-by: Maxwell Young <maxtheyoung@gmail.com>
Co-authored-by: Julius Marminge <julius0216@outlook.com>
Co-authored-by: codex <codex@users.noreply.github.com>
Co-authored-by: Yordis Prieto <yordis.prieto@gmail.com>
Co-authored-by: Alex <me@pixp.cc>
Co-authored-by: Chris Michael Guzman <67719167+Chrrxs@users.noreply.github.com>
Co-authored-by: Jake Leventhal <jakeleventhal@me.com>
Co-authored-by: Aditya Mer <101453576+Aditya190803@users.noreply.github.com>
Co-authored-by: Wout Stiens <71498452+StiensWout@users.noreply.github.com>
Co-authored-by: Codex <codex@openai.com>
Co-authored-by: ss <69873514+sandersonstabo@users.noreply.github.com>
Co-authored-by: Guilherme Vieira <46866023+GuilhermeVieiraDev@users.noreply.github.com>
Co-authored-by: Noah Zepner <noah@zepner.dev>
Co-authored-by: Utkarsh Patil <73941998+UtkarshUsername@users.noreply.github.com>
Co-authored-by: Taras <Taras.Fomin@gmail.com>
Co-authored-by: wizzoapp[bot] <254688279+wizzoapp[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Client clock skew persists future timestamps and reorders thread messages

2 participants